# 
# configuration_generator.rb
# 
# Created on 25/09/2007, 14:00:40
# 
 
# Build a nice output to default configuration.
module AutoRest
  module Configuration
    class ARDataContainer
      
      class FakeController
        attr_accessor :ar_controller_parents
        attr_accessor :controller_class_name
        attr_accessor :controller_name
        def initialize name
          self.ar_controller_parents= {}
          self.controller_name= name
          self.controller_class_name= "#{name.camelize}Controller"
        end
      end
      
      class FakeResource
        attr_accessor :path_prefix, :name_prefix, :collection_methods
        attr_accessor :plural, :singular
        def initialize name
          self.collection_methods= {}
          self.singular= name.downcase.singularize
          self.plural= name.downcase.pluralize
        end
      end
      
      class FakeModel
        attr_accessor :reflections, :class_name, :column_names, :name
        def initialize name
          self.name= name.downcase.singularize.camelize
          self.class_name= self.name
          self.reflections= []
          self.column_names= %w|attribute1 attribute2 etc|
        end
      end
      
      # This one generates the scaffold for a controller.
      def self.generator_helper res_name= "resource"
        
        prototipe= self.new
        prototipe.resource.model= FakeModel.new res_name
        prototipe.check_all_options(
          :resource => FakeResource.new(res_name), 
          :resources_parents => {}, 
          :controller => FakeController.new(res_name)
        )
        
        result= ""
        help= {}
        
        help[:parent_resources]= \
          "    # For parent_resources, each element must be a Struct::ARResource with this members:\n" \
          "    #   #{prototipe.resource.members.join(",")}.\n"
                
        help[:foreing_models]= \
          "    # For foreing models, hash must contain :foreign_key => ActiveRecordClass\n" \
          "    #    Example: {:zone_id => Zone}\n"
        
        prototipe.option_names.each do |opt_name|
          
          option= prototipe.send(opt_name)
          
          if option.class.ancestors.include? Struct
            result+= "    opt.#{opt_name} do |#{opt_name}|\n"
            
            option.members.each do |member|
              result+= "      #{opt_name}.#{member}= #{clean_value(option.send(member))}\n"
            end
            
            result+= "    end\n"
          else
            result+= help[opt_name] if help[opt_name]
            result+= handle_non_block_option(opt_name, option)
          end
          result+= "\n"
        end
        
        result
      end
      
      def self.handle_non_block_option opt_name, option
        result= ""
        case option
        when Hash
          return "    opt.#{opt_name}= {}\n" if option.size < 1
          option.each do |key, value| 
            result << "    opt.#{opt_name}[:#{key}]=".ljust(45) 
            result << "#{clean_value(value)}\n"
          end
        else
          result << "    opt.#{opt_name}= #{clean_value(option)}\n"
        end
        result
      end
      
      def self.clean_value(value)
        case value
        when AutoRest::Configuration::ARDataContainer::FakeModel
          value.name
        when Symbol
          ":#{value}"
        when String
          "\"#{value}\""
        when Hash
          result= []
          value.each { |key, value| result << ":#{key} => #{clean_value(value)}" }
          return "{ #{result.join(", ")} }"
        when Array, Set
          "[#{value.to_a.flatten.map{|e| clean_value(e)}.join(",") }]"
        when NilClass
          "nil"
        when Fixnum, TrueClass, FalseClass
          value
        else
          "#{value} # #{value.class}"
        end        
      end
    
    end
  end
end


